import React, { createContext, useState, useContext, useEffect, ReactNode } from 'react';
import { User, Tenant } from '../types';
import authService from '../services/auth';
import tenantService from '../services/tenants';

interface AuthContextType {
  user: User | null;
  currentTenant: Tenant | null;
  loading: boolean;
  login: (username: string, password: string) => Promise<void>;
  logout: () => void;
  updateUser: (user: User) => void;
  isAdmin: () => boolean;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export const useAuth = () => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within an AuthProvider');
  }
  return context;
};

interface AuthProviderProps {
  children: ReactNode;
}

export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
  const [user, setUser] = useState<User | null>(null);
  const [currentTenant, setCurrentTenant] = useState<Tenant | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const initAuth = async () => {
      const storedUser = authService.getStoredUser();
      if (storedUser && authService.isAuthenticated()) {
        try {
          const currentUser = await authService.getCurrentUser();
          setUser(currentUser);

          // Fetch tenant information (optional - only for display purposes)
          // If this fails, it won't affect the login process
          if (currentUser.tenantId) {
            try {
              const tenant = await tenantService.getTenant(currentUser.tenantId);
              setCurrentTenant(tenant);
            } catch (error: any) {
              // 403 Forbidden is expected for non-SystemAdministrator users
              // We'll just skip showing tenant name in the UI
              if (error.response?.status === 403) {
                console.log('Tenant information not accessible (requires SystemAdministrator role or matching tenant)');
              } else {
                console.error('Failed to get tenant:', error);
              }
              // Don't set currentTenant, it will remain null
            }
          }
        } catch (error) {
          console.error('Failed to get current user:', error);
          authService.logout();
        }
      }
      setLoading(false);
    };

    initAuth();
  }, []);

  const login = async (username: string, password: string) => {
    try {
      const response = await authService.login({ username, password });
      setUser(response.user);

      // Fetch tenant information (optional - only for display purposes)
      // If this fails, it won't affect the login process
      if (response.user.tenantId) {
        try {
          const tenant = await tenantService.getTenant(response.user.tenantId);
          setCurrentTenant(tenant);
        } catch (error: any) {
          // 403 Forbidden is expected for non-SystemAdministrator users
          // We'll just skip showing tenant name in the UI
          if (error.response?.status === 403) {
            console.log('Tenant information not accessible (requires SystemAdministrator role or matching tenant)');
          } else {
            console.error('Failed to get tenant:', error);
          }
          // Don't set currentTenant, it will remain null
        }
      }
    } catch (error) {
      // 重新抛出错误，让调用者处理
      throw error;
    }
  };

  const logout = () => {
    authService.logout();
    setUser(null);
    setCurrentTenant(null);
  };

  const updateUser = (updatedUser: User) => {
    setUser(updatedUser);
    localStorage.setItem('user', JSON.stringify(updatedUser));
  };

  const isAdmin = () => {
    return user?.roles?.some(role =>
      role === 'Administrator' || role === 'SystemAdministrator'
    ) || false;
  };

  const value = {
    user,
    currentTenant,
    loading,
    login,
    logout,
    updateUser,
    isAdmin,
  };

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};
